package com.sxpcwlkj.system.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import com.sxpcwlkj.authority.LoginObject;
import com.sxpcwlkj.common.code.controller.BaseController;
import com.sxpcwlkj.framework.entity.SmsBo;
import com.sxpcwlkj.common.code.entity.SmsConfigEntity;
import com.sxpcwlkj.common.enums.ConfigKeyNum;
import com.sxpcwlkj.common.exception.ServiceException;
import com.sxpcwlkj.common.utils.DataUtil;
import com.sxpcwlkj.common.utils.R;
import com.sxpcwlkj.redis.RedisUtil;
import com.sxpcwlkj.framework.utils.IPUtil;
import com.sxpcwlkj.sms.service.SmsService;
import com.sxpcwlkj.system.entity.vo.SysUserVo;
import com.sxpcwlkj.system.service.SysUserService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.*;

import java.time.Duration;
import java.util.*;

/**
 * @Description mms公共接口
 * @Author sxpcwlkj
 * @Version v1.0.0
 */
@RestController
@RequiredArgsConstructor
@Slf4j
@RequestMapping("common")
public class CommonController extends BaseController {
    private final SmsService smsService;
    private final SysUserService sysUserService;
    private final Environment environment;
    @GetMapping("/startBase")
    @SaIgnore
    public R<Object> startBase(){
        List<SmsConfigEntity> convert = RedisUtil.getCacheList(ConfigKeyNum.config_base.getKey());
        Map<String, Object> map = new HashMap<>();
        if(convert.isEmpty()){
            List<String> list=new ArrayList<>();
            list.add("1");
            map.put("loginType",list);
        }
        convert.forEach(smsConfigEntity -> {
            if("sys_base_title".equals(smsConfigEntity.getConfigKey())){
                map.put("globalTitle",smsConfigEntity.getConfigValue());
            }
            if("sys_base_description".equals(smsConfigEntity.getConfigKey())){
                map.put("globalDescription",smsConfigEntity.getConfigValue());
            }
            if("sys_base_logo".equals(smsConfigEntity.getConfigKey())){
                map.put("logo",smsConfigEntity.getConfigValue());
            }
            if("sys_base_captcha_state".equals(smsConfigEntity.getConfigKey())){
                map.put("captchaState", Convert.toInt(smsConfigEntity.getConfigValue())==1?true:false);
            }
            if("sys_base_login_type".equals(smsConfigEntity.getConfigKey())){
                map.put("loginType", DataUtil.getStringToList(smsConfigEntity.getConfigValue()));
            }
            if("sys_base_tenant_state".equals(smsConfigEntity.getConfigKey())){
                map.put("tenantState", Convert.toInt(smsConfigEntity.getConfigValue())==1?true:false);
            }
//            if("sys_base_tenant_exclusion_table".equals(smsConfigEntity.getConfigKey())){
//                map.put("tenantExclusionTable", DataUtil.getStringToList(smsConfigEntity.getConfigValue()));
//            }
        });
        return R.success("base system config.",map);
    }


    /**
     * 发送验证码
     * @param bo
     * @param request
     * @return
     */
    @SaIgnore
    @PostMapping("/smsCode")
    public R<Object> smsCode(@RequestBody SmsBo bo, HttpServletRequest request) {

        Integer type = bo.getType();

        String phone = bo.getPhone();

        String keytype = "register:";
        if (type == 1) {
            keytype = "register:";
        }
        if (type == 2) {
            List<SmsConfigEntity> convert = RedisUtil.getCacheList(ConfigKeyNum.config_base.getKey());
            for (SmsConfigEntity smsConfigEntity : convert) {
                if("sys_base_login_type".equals(smsConfigEntity.getConfigKey())){
                    List<String> toList = DataUtil.getStringToList(smsConfigEntity.getConfigValue());
                    if(toList.contains("1")){
                       return R.fail("当前系统不支持手机号登录！");
                    }
                }
            }

            keytype = "login:";
        }
        if (type == 3) {
            keytype = "password:";
        }
        if (type == 4) {
            keytype = "passwordPay:";
        }
        if (type == 5) {
            keytype = "updatePhone:";
        }
        if (environment.getProperty("spring.profiles.active").equals("prod")) {
            try {
                String ip = null;
                ip = IPUtil.getIp(request);
                log.info("ips:" + ip);
                Object s = RedisUtil.getCacheObject("ip:" + ip);
                int num = Convert.toInt(s == null ? 0 : Convert.toInt(s), 0);
                if (num >= 5) {
                    log.info("ips>=5,拦截:" + ip);
                    return R.fail("当前IP发送频繁,请一天后再发送哦！");
                }
                num++;
                RedisUtil.setCacheObject("ip:" + ip, num);
                RedisUtil.setCacheObject("ip:" + ip, num, Duration.ofDays(1));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        SysUserVo userVo = sysUserService.selectVoByPhone(phone);
        if (type == 1) {
            if (userVo != null) {
                return R.fail("该手机号已注册！");
            }
        }
        if (type == 2 || type == 3) {
            if (userVo == null) {
                return R.fail("该手机号账号不存在！");
            }
            if (Convert.toInt(userVo.getStatus()) != 1) {
                throw new ServiceException("账号状态不正常！");
            }
        }

        String key = RedisUtil.PHONE_CODES_KEY + keytype + phone;
        Object object = RedisUtil.getCacheObject(key);
        if (object != null) {
            RedisUtil.deleteObject(key);
            return R.fail("发送频繁,请稍后再发送哦！");
        }
        String code = RandomUtil.randomNumbers(6);
        R<Object> result = smsService.sendSms(phone, code);

        if (!result.getStatus()) {
            log.error("验证码短信发送异常 => {}", result.getMsg());
            return result;
        }
        RedisUtil.setCacheObject(key, code);
        RedisUtil.expire(key, Duration.ofMinutes(1));
        return R.success("手机短信码已发送！");
    }
}
